package com.syh.jn.scm.infrastructure.repository.impl.operation.supplier;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AbstractAggregateRepository;
import com.syh.jn.scm.domain.operation.entity.supplier.OperaSupplier;
import com.syh.jn.scm.domain.operation.repository.supplier.OperaSupplierRepository;
import com.syh.jn.scm.dto.operation.supplier.OperaSupplierAddressVo;
import com.syh.jn.scm.dto.operation.supplier.OperaSupplierVo;
import com.syh.jn.scm.infrastructure.repository.model.base.BusinessEntityAddressModel;
import com.syh.jn.scm.infrastructure.repository.model.base.SupplierModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import org.apache.ibatis.jdbc.SQL;
import org.hibernate.Query;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
public class OperaSupplierRepositoryImpl extends AbstractAggregateRepository<OperaSupplier, SupplierModel, Long> implements OperaSupplierRepository {
  /**
   * 运营新增供应商
   *
   * @param operaSupplier
   * @return
   */
  @Override
  public Long add(OperaSupplier operaSupplier) {
    Long id = super.add(operaSupplier);
    operaSupplier.getAddressItem().stream().forEach(address -> {
      BusinessEntityAddressModel addressModel = new BusinessEntityAddressModel();
      addressModel.setTerminalType("SUPPLIER");
      ExtBeanUtils.copyProperties(address, addressModel);
      addressModel.setBusinessEntityId(id);
      super.hibernateTemplate.save(addressModel);
    });
    return id;
  }

  /**
   * 运营修改供应商
   *
   * @param operaSupplier
   */
  @Override
  public void update(OperaSupplier operaSupplier, boolean isUpdateAddress) {
    if (isUpdateAddress) {
      this.update(operaSupplier);
    } else {
      super.update(operaSupplier);
    }
  }
  /**
   * 重载运营商修改
   *
   * @param operaSupplier
   */
  @Override
  public void update(OperaSupplier operaSupplier) {
    this.removeAddress(operaSupplier.getId());
    operaSupplier.getAddressItem().stream().forEach((address) -> {
      BusinessEntityAddressModel addressModel = new BusinessEntityAddressModel();
      addressModel.setTerminalType("SUPPLIER");
      ExtBeanUtils.copyProperties(address, addressModel);
      addressModel.setBusinessEntityId(operaSupplier.getId());
      super.hibernateTemplate.save(addressModel);
    });
    SupplierModel entityModel = this.hibernateTemplate.get(SupplierModel.class, operaSupplier.getId());
    ExtBeanUtils.copyProperties(operaSupplier, entityModel, false);
  }

  /**
   * 运营删除供应商
   *
   * @param operaSupplier
   */
  @Override
  public void remove(OperaSupplier operaSupplier) {
    this.removeAddress(operaSupplier.getId());
    super.remove(operaSupplier);
  }

  /**
   * 删除服务商所有地址
   *
   * @param supplierId
   */
  private void removeAddress(Long supplierId) {
    Query query = this.buildQuery("delete BusinessEntityAddressModel model where model.businessEntityId = :supplierId and model.terminalType = 'SUPPLIER' ");
    query.setLong("supplierId", supplierId);
    query.executeUpdate();

  }

  /**
   * 停用
   *
   * @param operaSupplier
   */
  @Override
  public void disabled(OperaSupplier operaSupplier) {
    super.update(operaSupplier);
  }

  /**
   * 启用
   *
   * @param operaSupplier
   */
  @Override
  public void enabled(OperaSupplier operaSupplier) {
    super.update(operaSupplier);
  }

  @Override
  public List<OperaSupplierAddressVo> getAddressListById(Long id) {
    StringBuffer hql = new StringBuffer();
    hql.append("from BusinessEntityAddressModel model where model.businessEntityId = ?  and model.terminalType = 'SUPPLIER' ");
    List<BusinessEntityAddressModel> OperaSupplierModelList = (List<BusinessEntityAddressModel>) this.hibernateTemplate.find(hql.toString(), id);
    if (OperaSupplierModelList.isEmpty()) {
      return Collections.emptyList();
    }
    return this.transAddressForm(OperaSupplierModelList);
  }


  /**
   * 内部方法  业务模型转LogisticsAddressVo
   *
   * @param entityList
   * @return
   */
  private List<OperaSupplierAddressVo> transAddressForm(List<BusinessEntityAddressModel> entityList) {
    List<OperaSupplierAddressVo> voList = new ArrayList<>();
    entityList.stream().forEach((entity) -> {
      OperaSupplierAddressVo vo = new OperaSupplierAddressVo();
      ExtBeanUtils.copyProperties(entity, vo);
      voList.add(vo);
    });
    return voList;
  }

  @Override
  protected BaseResolve getViewWrapperResolve(Wrapper wrapper) {
    Map<String, String> params = new HashMap<>();
    params.put("legalRepresentative", "sp.LEGAL_REPRESENTATIVE");
    params.put("tel", "sp.TEL");
    params.put("registrationCode", "sp.REGISTRATION_CODE");
    params.put("isSubsidiary", "sp.IS_SUBSIDIARY");
    params.put("name", "sp.NAME");
    params.put("id", "sp.ID");
    params.put("status", "sp.status");
    ResolveToSQL parse = new ResolveToSQL(wrapper, (propertyName) -> {
      return params.get(propertyName);
    });
    return parse;
  }

  @Override
  protected SQL getViewSql() {
    return new SQL() {{
      SELECT(SQLAliasGenerateUtil.aliasGenerate(SupplierModel.class, "sp", null),
              "sp_user.ID AS accountId",
              "sp_user.LOGIN_ACCOUNT AS account"
      );
      FROM("T_BASE_SUPPLIER AS sp");
      LEFT_OUTER_JOIN("T_SYSTEM_ACCOUNT sp_user ON sp.ID = sp_user.BUSINESS_ENTITY_ID AND sp_user.ADMIN = 1 AND sp_user.ROLE_ID = 0 AND sp_user.TERMINAL_TYPE = 'SUPPLIER'");
    }};
  }

  @Override
  protected Class getViewObject() {
    return OperaSupplierVo.class;
  }
}
